package com.pb.metadata.service;


import com.pb.infra.oth.entity.common.Result;
import com.pb.infra.oth.util.ExcelUtil;
import com.pb.infra.oth.util.JwtTokenConfig;
import com.pb.metadata.entity.ImportDimData;
import com.pb.metadata.mapper.DimManagementMapper;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 维度管理
 * 2023/2/7
 */
@Service
public class DimManagementService {
    /**
     * DAO映射对象
     */
    @Resource
    private DimManagementMapper dimManagementMapper;

    /**
     * jwttoken配置类
     */
    @Resource
    private JwtTokenConfig jwtTokenConfig;

    //查询最大CodeTypeId
    public Long selMaxCodeTypeId(Map<String, Object> map) {
        return dimManagementMapper.selMaxCodeTypeId(map);
    }

    //创建维度管理数据
    @Transactional
    public Result saveDimDate(Map<String, Object> map) {
        Long codeTypeId = selMaxCodeTypeId(map) + 1;
        map.put("codeTypeId",codeTypeId + "");
        map.put("debugFlag","0");
        map.put("deleteFlag","0");
        map.put("recordSts","FREE");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("createTime",format.format(new Date()));
        map.put("updateTime",format.format(new Date()));
        //查询当前职位所属法人
        String corpId = dimManagementMapper.selPostCorpId(map.get("positionId"));
        map.put("corpId",corpId);
        //插入维度树
        dimManagementMapper.saveDimDate(map);
        //维度树、维度类型绑定
        dimManagementMapper.saveDimTreeBind(map);
        return Result.OK_EMPTY;
    }

    //查询维度管理数据
    public Result selectDimData(Map<String, Object> map) {
        return Result.ok(dimManagementMapper.selectDimData(map));
    }


    public Result selectComDimData(Map<String, Object> map) {
        return Result.ok(dimManagementMapper.selectComDimData(map));
    }

    //修改维度管理数据
    @Transactional
    public Result updateDimDate(Map<String, Object> map) {
        SimpleDateFormat format = new SimpleDateFormat(" yyyy-MM-dd HH:mm:ss");
        map.put("updateTime",format.format(new Date()));
        dimManagementMapper.updateDimDate(map);
        return Result.OK_EMPTY;
    }

    //删除维度管理数据
    @Transactional
    public Result delDimDate(Map<String, Object> map) {
        dimManagementMapper.delDimDate(map);
        dimManagementMapper.delTreeNode(map);
        //删除绑定数据
        dimManagementMapper.delDimBind(map);
        return Result.OK_EMPTY;
    }

    //查询维度树
    public Result selectTree(Map<String, Object> map) {
        List<Map<String, Object>> maps = dimManagementMapper.selectTree(map);
        return Result.ok(maps);
    }

    @Transactional
    public Result insertNode(Map<String, Object> paramMap) {
        //获取最大codeId
        if(dimManagementMapper.selMaxCodeId(paramMap) != null){
            Long codeId = dimManagementMapper.selMaxCodeId(paramMap);
            paramMap.put("codeId",(codeId + 1) + "");
        }else {
            paramMap.put("codeId",1 + "");
        }
        //0未删除，1已删除
        paramMap.put("deleteFlag","0");

        //默认1，是否启用
        paramMap.put("activeFlag","1");

        //获取同级别最大orderFlag
        if(dimManagementMapper.selMaxOrderFlag(paramMap) != null){
            Long orderFlag = dimManagementMapper.selMaxOrderFlag(paramMap);
            paramMap.put("orderFlag",(orderFlag + 1) + "");
        }else {
            paramMap.put("orderFlag",1 + "");
        }
        paramMap.put("nodePath", null);
//        paramMap.put("remarks","");
        dimManagementMapper.insertNode(paramMap);
        return Result.OK_EMPTY;
    }

    //查询编码是否唯一
    public Result validUnique(Map<String, Object> paramMap) {
        Map map = dimManagementMapper.selectByTreeId(paramMap);
        if (map == null) {
            return Result.ok(true);
        } else {
            return Result.ok(false);
        }
    }

    //删除树节点
    @Transactional
    public Result deleteNode(Map<String, Object> paramMap) {
        String corpId = paramMap.get("corpId").toString();
        String treeId = paramMap.get("treeId").toString();
        String tableName = paramMap.get("tableName").toString();
        List list = (List) paramMap.get("indIds");
        dimManagementMapper.deleteNode(tableName,corpId,treeId,list);
        return Result.ok("删除成功");
    }

    //查询全部对应树节点，导出数据
    public List<Map<String, Object>> selTreeData(Map<String, Object> map) {
        return dimManagementMapper.selTreeData(map);
    }

    //修改树节点数据
    @Transactional
    public Result updateNode(Map<String, Object> paramMap) {
        dimManagementMapper.updateNode(paramMap);
        return Result.OK_EMPTY;
    }

    //修改节点层级(拖拽)
    @Transactional
    public Result updateNodeHierarchy(Map<String, Object> paramMap) {
        dimManagementMapper.updateNodeHierarchy(paramMap);
        return Result.OK_EMPTY;
    }

    //查询关联码值列表
    public Result getrelaStdCodeList(Map<String, Object> map) {
        List<Map<String, Object>> list = dimManagementMapper.getrelaStdCodeList(map);
        return Result.ok(list);
    }

    //查询维度类型列表
    public Result selDimTypeList(Map<String, Object> map) {
        List<Map<String, Object>> list = dimManagementMapper.selDimTypeList(map);
        return Result.ok(list);
    }

    //属性注册
    public Result dimAttrTableData(Map<String, Object> paramMap) {
        return Result.ok(dimManagementMapper.dimAttrTableData(paramMap));
    }

    //查询关联码值对应标准编码
    @Transactional
    public Result getmateCodeValueList(Map<String, Object> paramMap) {
        //查询关联标准编码codeTypeId
//        String codeTypeId = dimManagementMapper.selRelaCodeTypeId(paramMap);
        Map map = dimManagementMapper.selRelaCodeTypeId(paramMap);
        List<Map<String, Object>> list = dimManagementMapper.getmateCodeValueList(map);
        return Result.ok(list);
    }

    //保存维度类型值
    @Transactional
    public Result saveDimAttrTableData(List<Map<String, Object>> paramMap) {
        //先删除叶子结点对应属性值
        for (Map<String, Object> map : paramMap) {
            dimManagementMapper.delDimAttrTableData(map);
        }
        //再重新添加
        for (Map<String, Object> map : paramMap) {
            dimManagementMapper.saveDimAttrTableData(map);
        }
        return Result.OK_EMPTY;
    }

    public Result validUniqueBusinessCodeType(Map<String, Object> map) {
        Map paramMap = dimManagementMapper.validUniqueBusinessCodeType(map);
        if (paramMap == null) {
            return Result.ok(true);
        } else {
            return Result.ok(false);
        }
    }

    @Transactional
    public Object checkExcelData(Map<String, Object> paramMap, XSSFWorkbook workbook, int startRowNum, int sheetCount) {
        List<ImportDimData> importDimDataList = new ArrayList<>();   //导入list数据集合
        boolean hasErr = false;                              //存在错误标志位
        StringBuilder errInfo = new StringBuilder();         //全局错误信息
        StringBuilder rowErrInfo = new StringBuilder();      //行错误信息
        //HashSet<String> primaryKeySet = new HashSet<>();     //主键集（辅助检查主键是否重复）
        String codeTypeId = paramMap.get("codeTypeId") + "";
        String corpId = paramMap.get("corpId") + "";
        String tableName = paramMap.get("tableName") + "";
        int totalCellCount = 0;
        Map<String, Object> importDataMap = new HashMap<>();
        DataFormatter formatter = new DataFormatter();
        Integer codeId = 1;  // 节点唯一标识，自增
        rowErrInfo.append("<br/>");
        rowErrInfo.append("**********   <span style='color:red;font-weight:bold;'>导入结果：失败</span>   **********");
        //遍历工作薄
        XSSFSheet sheet = workbook.getSheetAt(0);

        if (sheet.getLastRowNum() > 1) {
            XSSFRow row2 = sheet.getRow(1);
            totalCellCount = row2.getLastCellNum();
        }

        //行
        for (int i = startRowNum; i <= sheet.getLastRowNum(); i++) {
            //遍历每一行（从工作簿第startDataRow行开始读取）
            XSSFRow row = sheet.getRow(i);
            if (row != null && !ExcelUtil.concatString(row, totalCellCount, formatter)) {
                int cellCount = row.getLastCellNum();
                //每行数据
                String[] importData = new String[totalCellCount];
                //列
                if(cellCount % 2 == 0){
                    for (int j = 0; j < cellCount; j+=2) {
                        ImportDimData importDimData = new ImportDimData();
                        XSSFCell cell = row.getCell(j);
                        String cellValue = ExcelUtil.getStringCellValues(formatter, cell);
//                        System.out.println("cellValue------->" + cellValue);
                        if (importDataMap.containsKey(cellValue)) {
                            ImportDimData importDataMapValue = (ImportDimData) importDataMap.get(cellValue);
                            if (j == cellCount - 2) {
                                rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第" + (i + 1) + "行" + (j + 1) + "列数据有误,存在重复叶子节点业务编码");
                                return rowErrInfo.toString();
                            } else if (j == 0) {
                                if (!importDataMapValue.getUpperId().equals("0")) {
                                    rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第" + (i + 1) + "行" + (j + 1) + "列数据有误,该节点的父节点不为根目录");
                                    return rowErrInfo.toString();
                                } else {
                                    continue;
                                }
                            } else {
                                if (!importDataMapValue.getUpperBusinessCode().equals(ExcelUtil.getStringCellValues(formatter, row.getCell(j - 2)))) {
                                    rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第" + (i + 1) + "行" + (j + 1) + "列数据有误,该节点与父节点(" + ExcelUtil.getStringCellValues(formatter, row.getCell(j - 2)) + ")关系存在错误");
                                    return rowErrInfo.toString();
                                } else {
                                    continue;
                                }
                            }
                        } else {
                            //节点ID
                            importDimData.setCodeId(codeId + "");
                            //节点业务编号
                            importDimData.setBusinessCode(cellValue + "");
                            //节点名称
                            importDimData.setCnName(row.getCell(j + 1) + "");
                            //节点层级
                            importDimData.setLvl((j / 2 + 1));
                            //是否生效
                            importDimData.setActiveFlag("1");
                            //删除标志
                            importDimData.setDeleteFlag("0");
                            //排序标识
                            importDimData.setOrderFlag(codeId + "");
                            //树ID
                            importDimData.setCodeTypeId(codeTypeId);
                            //法人ID
                            importDimData.setCorpId(corpId);
                            //表名
                            importDimData.setTableName(tableName);
                            //节点叶子标识
                            if (j == cellCount - 2) {
                                importDimData.setLeafFlag("1");
                            } else {
                                importDimData.setLeafFlag("0");
                            }
                            //父节点
                            if (j == 0) {
                                importDimData.setUpperId("0");
                                importDimData.setUpperBusinessCode(null);
                            } else {
                                String upperNodeBusinessCode = ExcelUtil.getStringCellValues(formatter, row.getCell(j - 2));
                                List<ImportDimData> filterImportDimList = importDimDataList.stream().filter(filterImportDimData1 -> filterImportDimData1.getBusinessCode().equals(upperNodeBusinessCode)).collect(Collectors.toList());
                                filterImportDimList.forEach(System.out::println);
                                System.out.println("----------------------");
                                importDimData.setUpperId(filterImportDimList.get(0).getCodeId());
                                importDimData.setUpperBusinessCode(filterImportDimList.get(0).getBusinessCode());
                            }
                            //加入列表
                            importDimDataList.add(importDimData);
                            //加入校验Map检查重复
                            importDataMap.put(cellValue,importDimData);
                            //codeId自增
                            codeId += 1;
                        }
                    }
                }else {
                    rowErrInfo.append("<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第 " + (i + 1) + " 行数据有误");
                    return rowErrInfo.toString();
                }
            }
        }
        return importDimDataList;
    }

    /**
     * 消除小数点格式
     * @return StringBuilder
     */
    private String changeCellType(XSSFCell cell) {
        String cellValue = cell.toString();
        if (cellValue.contains(".")) {
            cellValue = cellValue.substring(0,cellValue.indexOf('.'));
        }
        return cellValue;
    }

    // 导入时，全量删除树节点
    @Transactional
    public void delAllTreeNode(Map<String, Object> paramMap) {
        dimManagementMapper.delAllTreeNode(paramMap);
    }

    @Transactional
    public void insertExcelData(List<ImportDimData> checkList) {
        for (ImportDimData importDimData : checkList) {
            dimManagementMapper.insertExcelData(importDimData);
        }
    }

    public Result selDefaultCheckedTreeNodeList(Map<String, Object> map) {
        List<String> defaultCheckedTreeNodeBusinessCodeList = dimManagementMapper.selDefaultCheckedTreeNodeBusinessCode(map);
        map.put("list",defaultCheckedTreeNodeBusinessCodeList);
        if (defaultCheckedTreeNodeBusinessCodeList.size() != 0) {
            List<String> defaultCheckedTreeNodeList = dimManagementMapper.selDefaultCheckedTreeNodeList(map);
            return Result.ok(defaultCheckedTreeNodeList);
        }
        return Result.OK_EMPTY;
    }

    @Transactional
    public Result saveNodesAttrValues(List<Map<String, Object>> list) {
        if (list.size() > 0) {
            //先删除
            dimManagementMapper.delNodesAttrValues(list);
            //循环插入
            dimManagementMapper.saveNodesAttrValues(list);
        }
        return Result.OK_EMPTY;
    }
}
